package com.ksyun.campus.metaserver.controller;

import com.ksyun.campus.metaserver.domain.BlockInfo;
import com.ksyun.campus.metaserver.domain.FileType;
import com.ksyun.campus.metaserver.domain.StatInfo;
import com.ksyun.campus.metaserver.domain.dto.ApiResponse;
import com.ksyun.campus.metaserver.services.IMetaService;

import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Replica layout and information controller
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/replica")
public class ReplicaController {
    
    @Autowired
    private IMetaService metaService;
    /**
     * Get replica layout for a file
     */
    /**
     * 控制器：ReplicaController

     * 主要功能：查询指定文件在集群中的副本布局（Replica Layout）。
     * 副本布局信息包含：
     *  - 文件每个数据块（Block）的索引编号
     *  - 每个块的多个副本所在的数据节点（DataNode）的地址、端口、角色等
     * 典型使用场景：
     *  - 管理员查看文件的三副本分布是否均衡
     *  - 调试副本丢失、数据修复（FSCK）等功能
     * 请求示例：
     *  GET /layout?path=/user/test/file.txt
     *
     * 返回示例：
     * {
     *   "fileId": "f12345",
     *   "blocks": [
     *       {
     *           "blkIdx": 0,
     *           "size": 524288,
     *           "replicas": [
     *               {"dsId": "dn1", "host": "10.0.0.1", "port": 50010, "role": "PRIMARY"},
     *               {"dsId": "dn2", "host": "10.0.0.2", "port": 50010, "role": "SECONDARY"}
     *           ]
     *       },
     *       ...
     *   ]
     * }
     */
    @GetMapping("/layout")
    public ApiResponse<Map<String, Object>> getReplicaLayout(@RequestParam String path) {
        try {
            // Get file status to resolve file ID
            StatInfo status = metaService.getStatus(path);
            if (status.getType() != FileType.FILE) {
                return ApiResponse.error("Path is not a file: " + path);
            }
            
            // TODO: Properly resolve path to file ID
            String fileId = status.getPath(); // This needs to be fixed
            
            List<BlockInfo> blocks = metaService.getFileBlocks(fileId);
            
            List<Map<String, Object>> blockLayouts = blocks.stream().map(block -> {
                List<Map<String, Object>> replicas = block.getReplicas().stream().map(replica -> {
                    Map<String, Object> replicaInfo = new HashMap<>();
                    replicaInfo.put("dsId", replica.getDsId());
                    replicaInfo.put("host", replica.getHost());
                    replicaInfo.put("port", replica.getPort());
                    replicaInfo.put("role", replica.getRole().toString());
                    return replicaInfo;
                }).collect(Collectors.toList());
                
                Map<String, Object> blockLayout = new HashMap<>();
                blockLayout.put("blkIdx", block.getBlkIdx());
                blockLayout.put("replicas", replicas);
                blockLayout.put("size", block.getSize());
                return blockLayout;
            }).collect(Collectors.toList());
            
            return ApiResponse.success(Map.of(
                    "fileId", fileId,
                    "blocks", blockLayouts
            ));
        } catch (Exception e) {
            log.error("Error getting replica layout for path: {}", path, e);
            return ApiResponse.error(e.getMessage());
        }
    }
}
